/**
 * @this RXFormItem: form 基础控件
 *
 * @flow
 */
import React, { Component } from 'react'
import {
  StyleSheet,
  View,
  Text,
  Image,
  ViewPropTypes,
  TouchableOpacity,
} from 'react-native'

import PropTypes from 'prop-types'

import RXSeparator from './RXSeparator'
import FormStyle from './config/FormStyle'

export default class RXFormItem extends Component {
  constructor(props) {
    super(props)
  }

  static propTypes = {
    ...TouchableOpacity.propTypes,
    title: PropTypes.oneOfType([PropTypes.element, PropTypes.string, PropTypes.number]),
    detail: PropTypes.oneOfType([PropTypes.element, PropTypes.string, PropTypes.number]),
    titleStyle: Text.propTypes.style,
    detailStyle: Text.propTypes.style,
    isMust: PropTypes.bool,
    mustStyle: Text.propTypes.style,
    iconStyle: ViewPropTypes.style,
    icon: PropTypes.oneOfType([PropTypes.element, PropTypes.shape({ uri: PropTypes.string }), PropTypes.number]),
    titlePlace: PropTypes.oneOf(['left', 'top']),
    accessory: PropTypes.oneOfType([PropTypes.element, PropTypes.shape({ uri: PropTypes.string }), PropTypes.number, PropTypes.oneOf(['none', 'auto', 'indicator'])]),
    accessoryStyle: Image.propTypes.style,
    topSeparator: PropTypes.oneOfType([PropTypes.element, PropTypes.oneOf(['none', 'full', 'indent'])]),
    bottomSeparator: PropTypes.oneOfType([PropTypes.element, PropTypes.oneOf(['none', 'full', 'indent'])]),
    enable: PropTypes.bool,
    pointerEvents: PropTypes.string,
  }

  static defaultProps = {
    ...TouchableOpacity.defaultProps,
    isMust: false,
    activeOpacity: null,
    accessory: 'auto',
    topSeparator: 'none',
    bottomSeparator: 'indent',
    titlePlace: 'left',
    enable: true,
    pointerEvents: 'auto',
  }

  renderContent() {
    let { icon, iconStyle, title, titleStyle, detail, detailStyle, titlePlace, isMust, mustStyle } = this.props

    // icon
    if ((icon || icon === 0) && !React.isValidElement(icon)) {
      iconStyle = [{
        width: FormStyle.ItemIconWidth,
        height: FormStyle.ItemIconHeight,
        paddingRight: FormStyle.ItemIconPaddingRight,
      }].concat(iconStyle)
      icon = (
        <Image style={[iconStyle]} source={icon} />
      )
    }

    // title
    if (typeof title === 'string' || typeof title === 'number') {
      titleStyle = [{
        color: FormStyle.ItemTitleColor,
        fontSize: FormStyle.ItemTitleFontSize,
      }].concat(titleStyle)
      const textStyle = (!detail && titlePlace === 'left') ? { flexGrow: 1, flexShrink: 1 } : null
      title = <Text style={[textStyle, titleStyle]} >{title}{
        isMust ? <Text style={[{
          color: FormStyle.ItemMustColor,
        }, mustStyle]} > *</Text> : null
      }</Text >
    }

    // detail
    if (typeof detail === 'string' || typeof detail === 'number') {
      detailStyle = [{
        color: FormStyle.ItemDetailColor,
        fontSize: FormStyle.ItemDetailFontSize,
      }].concat(detailStyle)
      const textStyle = titlePlace === 'top' ? {} : { flexGrow: 1, flexShrink: 1, textAlign: 'right' }
      if (title) {
        if (titlePlace === 'left') {
          textStyle.paddingLeft = FormStyle.ItemPaddingTitleDetail
        } else {
          textStyle.paddingTop = FormStyle.ItemPaddingTitleDetail
        }
      }
      detail = <Text style={[textStyle, detailStyle]} >{detail}</Text>
    }
    return { icon, title, detail }
  }

  renderAccessory() {
    let { accessory, accessoryStyle, onPress } = this.props

    if (accessory === 'none') {
      accessory = null
    } else if (accessory === 'auto') {
      accessory = onPress ? 'indicator' : null
    }

    if (accessory && !React.isValidElement(accessory)) {
      let imageSource
      if (accessory === 'none') {
        imageSource = null
      } else if (accessory === 'indicator') {
        imageSource = FormStyle.ItemAccessoryIndicator
      } else {
        imageSource = accessory
      }

      accessoryStyle = [{
        width: FormStyle.ItemAccessoryWidth,
        height: FormStyle.ItemAccessoryHeight,
        marginLeft: FormStyle.ItemAccessoryPaddingDetail,
      }].concat(accessoryStyle)

      accessory = React.isValidElement(imageSource) ? imageSource : (
        <Image style={accessoryStyle} source={imageSource} />
      )
    }
    return accessory
  }

  render() {
    let { style, activeOpacity, onPress, titlePlace, contentStyle, topSeparator, bottomSeparator, onLayout, children, enable, pointerEvents, ...others } = this.props
    const { icon, title, detail } = this.renderContent()
    const accessory = this.renderAccessory()

    // style
    style = [styles.container, {
      paddingLeft: FormStyle.ItemPaddingLeft,
      paddingRight: FormStyle.ItemPaddingRight,
      minHeight: FormStyle.ItemMinHeight,
      backgroundColor: FormStyle.ItemBgColor,
      paddingTop: titlePlace === 'top' ? FormStyle.ItemPaddingLeft : FormStyle.ItemPaddingTop,
      paddingBottom: titlePlace === 'top' ? FormStyle.ItemPaddingRight : FormStyle.ItemPaddingBottom,
    }].concat(style)

    // activeOpacity
    if (!activeOpacity && activeOpacity !== 0) activeOpacity = onPress ? 0.2 : 1

    // contentStyle
    contentStyle = {
      flex: 1,
      overflow: 'hidden',
      flexDirection: titlePlace === 'top' ? 'column' : 'row',
      alignItems: titlePlace === 'top' ? 'stretch' : 'center',
      justifyContent: 'space-between',
    }

    //  topSeparator and bottomSeparator
    const indentViewStyle = {
      backgroundColor: StyleSheet.flatten(style).backgroundColor,
    }

    if (topSeparator && !React.isValidElement(topSeparator)) {
      topSeparator = <RXSeparator style={indentViewStyle} type={topSeparator} />
    }

    if (bottomSeparator && !React.isValidElement(bottomSeparator)) {
      bottomSeparator = <RXSeparator style={indentViewStyle} type={bottomSeparator} />
    }

    if (!enable) {
      pointerEvents = 'none'
    }
    // console.log('title='+ this.props.title+', pointerEvents='+pointerEvents)
    return (
      <View onLayout={onLayout} pointerEvents={pointerEvents}>
        {topSeparator}
        <TouchableOpacity {...others}
          style={style}
          activeOpacity={activeOpacity}
          onPress={onPress}
        >
          {icon}
          {!title && !detail ? null
            : <View style={contentStyle}>
                {title}
                {detail}
              </View>
          }
          {!title && !detail ? children : null}
          {accessory}
        </TouchableOpacity>
        {bottomSeparator}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    overflow: 'hidden',
    flexDirection: 'row',
    alignItems: 'center',
  },
})